package com.rybbaby.tss.platform.tags;

import com.rybbaby.tss.core.utils.StringUtils;
import com.rybbaby.tss.platform.consts.PlatformCommonConsts;
import com.rybbaby.tss.platform.initializer.HandlePermissionsInitializer;
import com.rybbaby.tss.platform.sysHandlePermissions.entity.SysHandlePermissions;
import com.rybbaby.tss.platform.sysHandlePermissionsAttrs.entity.SysHandlePermissionsAttrs;
import com.rybbaby.tss.platform.sysHandlePermissionsClasses.entity.SysHandlePermissionsClasses;
import com.rybbaby.tss.platform.sysHandlePermissionsEvents.entity.SysHandlePermissionsEvents;
import com.rybbaby.tss.platform.sysHandlePermissionsStyles.entity.SysHandlePermissionsStyles;
import com.rybbaby.tss.platform.tags.pojo.Permission;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @description 权限标签,对系统的所有操作权限进行控制
 * 
 * @author 谢进伟
 * 
 * @createDate 2016年11月24日 下午9:04:13
 */
public class PermissionTag extends BodyTagSupport implements TemplateDirectiveModel {
	
	private static final long serialVersionUID = 1L;
	/** 参数容器 **/
	private Map<String , Object> paramsMap = new HashMap<String , Object>();
	/** 传入的参数 **/
	private String params;
	/** 权限按钮编码 **/
	private String code;
	/** 权限参数分隔符 **/
	private String separator = ",";
	
	@Autowired
	protected HttpServletRequest request;
	
	/*************************************** 针对freemarker视图的标签实现 ***************************************************/
	@Override
	@SuppressWarnings("rawtypes")
	public void execute(Environment env , Map args , TemplateModel [] loopVars , TemplateDirectiveBody body) throws TemplateException , IOException {
		this.code = args.get("code").toString();
		if(code == null) {
			throw new IllegalArgumentException("参数'code' 是必须的!");
		}
		Object paramsObj = args.get("params");
		Object separatorObj = args.get("separator");
		this.params = paramsObj == null ? null : paramsObj.toString();
		this.separator = separatorObj == null ? this.separator : separatorObj.toString();
		init();
		long start = System.currentTimeMillis();
		env.getOut().append(getHandlepermissionOutputStr());

	}
	
	/*************************************** 针对jsp视图使的标签实现 ***************************************************/
	@Override
	public int doStartTag() throws JspException {
		init();
		return super.doStartTag();
	}
	
	@Override
	public int doEndTag() throws JspException {
		JspWriter out = this.pageContext.getOut();
		try {
			String str = "";
			str = getHandlepermissionOutputStr();
			out.print(str);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return super.doEndTag();
	}
	
	/**
	 * 初始化传入参数
	 */
	private void init() {
		if(this.params != null) {
			if(this.params.matches("^\\[[a-zA-Z_]+\\w*=[^=]*(" + separator + "[a-zA-Z_]+\\w*=[^=]*)*\\]$")) {
				int indexOf = this.params.indexOf("[") + 1;
				int lastIndexOf = this.params.lastIndexOf("]");
				if(this.params.length() > 2) {
					params = StringUtils.substring(this.params , indexOf , lastIndexOf);
				}
				this.paramsMap.clear();
				for(String param : params.split(",")) {
					String [] paramItem = param.split("=");
					if(paramItem.length > 1) {
						this.paramsMap.put(paramItem[0] , paramItem[1]);
					} else {
						this.paramsMap.put(paramItem[0] , "");
					}
				}
			} else {
				throw new IllegalArgumentException("params 参数格式错误,参数格式为'[name1=value1,name2=value2,name3=value3...]'");
			}
		}
	}
	
	/**
	 * 获取权限输出字符串
	 * 
	 * @return
	 */
	private String getHandlepermissionOutputStr() {
		if(StringUtils.isBlank(code)) {
			return "";
		}
		StringBuffer handlePermissionOutStr = new StringBuffer();
		Object loginUserId = request.getSession().getAttribute(PlatformCommonConsts.SESSION_LOGINUSER_OBJ_ID);
		// 从缓存中获取操作权限
		SysHandlePermissions shp = HandlePermissionsInitializer.getCacheHandlePermission(loginUserId , code);
		if(shp != null && shp.getIsForbidden() != null && !shp.getIsForbidden()) {
			// 权限
			Permission permission = new Permission();
			permission.setId(shp.getIdAttr());
			permission.setTagName(shp.getTagName());
			permission.setInnerHtml(shp.getInnerHtml());
			permission.setCode(shp.getCode());
			permission.setPageName(shp.getPageName());
			// 权限自定义属性
			setAttr(shp , permission);
			// 权限自定义class
			setClasses(shp , permission);
			// 权限指定一行内样式
			addStyles(shp , permission);
			// 权限指自定义事件
			bindEvent(shp , permission);
			// 设置参数
			setParam(permission);
			handlePermissionOutStr.append(permission);
		}
		return handlePermissionOutStr.toString();
	}
	
	/**
	 * 设置参数
	 * 
	 * @param permission
	 *            权限对象
	 */
	private void setParam(Permission permission) {
		if(paramsMap != null && !paramsMap.isEmpty()) {
			if(this.paramsMap != null && !this.paramsMap.isEmpty()) {
				Set<String> keys = this.paramsMap.keySet();
				for(String paramKey : keys) {
					Object value = this.paramsMap.get(paramKey);
					permission.setParams(paramKey , value);
				}
			}
		}
	}
	
	/**
	 * 绑定事件
	 * 
	 * @param shp
	 * @param permission
	 */
	private void bindEvent(SysHandlePermissions shp , Permission permission) {
		List<SysHandlePermissionsEvents> events = shp.getEvents();
		if(events != null && !events.isEmpty()) {
			for(SysHandlePermissionsEvents event : events) {
				if(event.getIsForbidden() == null || event.getIsForbidden()) {
					continue;// 被禁用的style不添加
				}
				permission.addEvent(event.getName() , StringEscapeUtils.unescapeJavaScript(event.getFunction()));
			}
		}
	}
	
	/**
	 * 添加样式
	 * 
	 * @param shp
	 * @param permission
	 */
	private void addStyles(SysHandlePermissions shp , Permission permission) {
		List<SysHandlePermissionsStyles> styles = shp.getStyles();
		if(styles != null && !styles.isEmpty()) {
			for(SysHandlePermissionsStyles style : styles) {
				if(style.getIsForbidden() == null || style.getIsForbidden()) {
					continue;// 被禁用的style不添加
				}
				permission.addStyle(style.getName() , style.getValue());
			}
		}
	}
	
	/**
	 * 添加自定义class属性
	 * 
	 * @param shp
	 * @param permission
	 */
	private void setClasses(SysHandlePermissions shp , Permission permission) {
		List<SysHandlePermissionsClasses> classes = shp.getClasses();
		if(classes != null && !classes.isEmpty()) {
			for(SysHandlePermissionsClasses cls : classes) {
				if(cls.getIsForbidden() == null || cls.getIsForbidden()) {
					continue;// 禁用的class不添加
				}
				permission.addClasse(cls.getName());
			}
		}
	}
	
	/**
	 * 添加自定义属性
	 * 
	 * @param shp
	 * @param permission
	 */
	private void setAttr(SysHandlePermissions shp , Permission permission) {
		List<SysHandlePermissionsAttrs> attrs = shp.getAttrs();
		if(attrs != null && !attrs.isEmpty()) {
			for(SysHandlePermissionsAttrs attr : attrs) {
				if(attr.getIsForbidden() == null || attr.getIsForbidden()) {
					continue;// 禁用的属性不添加
				}
				permission.addAttr(attr.getName() , attr.getValue());
			}
		}
	}
	
	/**
	 * 接收权限编码
	 * 
	 * @param code
	 *            权限编码
	 */
	public void setCode(String code) {
		this.code = code;
	}
	
	/**
	 * 接收权限所需的参数
	 * 
	 * @param params
	 *            参数字符串
	 */
	public void setParams(String params) {
		this.params = params;
	}
	
	/**
	 * 传入的全下你参数字符串中各参数分隔符
	 * 
	 * @param separator
	 *            参数之间的分隔符
	 */
	public void setSeparator(String separator) {
		this.separator = separator;
	}
}
